package com.koko.controller;

import com.koko.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.List;

/**
 * 文件上传和下载
 */
@Slf4j
@RestController
@RequestMapping("/game/common")
public class CommonController {

    @Value("${koko.path.publisher}")
    private String publisherBasePath;

    @Value("${koko.path.game}")
    private String gameBasePath;

    /**
     *
     * @param file
     * @return
     */
    @PostMapping("/publisher/upload")
    public Result<String> upload(MultipartFile file) {
        return null;
    }

    @GetMapping("/publisher/download")
    public void publisherIconDownload(@RequestParam String id, @RequestParam String name, HttpServletResponse response) {
        try {
            //输入流，通过输入流读取文件内容
            FileInputStream fileInputStream = new FileInputStream(new File(publisherBasePath + id + "/" + name));
            //输出流，通过输出流将文件写回浏览器，在浏览器展示图片了
            ServletOutputStream outputStream = response.getOutputStream();

            response.setContentType("image/jpeg");

            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = fileInputStream.read(bytes)) != -1){
                outputStream.write(bytes, 0,len);
                outputStream.flush();
            }

            outputStream.close();
            fileInputStream.close();
        } catch (Exception e) {
            log.error("系统未找到指定文件");
        }
    }

    @GetMapping("/download")
    public void gamePictureDownload(@RequestParam String id, @RequestParam String name, HttpServletResponse response) {
        try {
            //输入流，通过输入流读取文件内容
            FileInputStream fileInputStream = new FileInputStream(new File(gameBasePath + id + "/" + name));
            //输出流，通过输出流将文件写回浏览器，在浏览器展示图片了
            ServletOutputStream outputStream = response.getOutputStream();

            response.setContentType("image/jpeg");

            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = fileInputStream.read(bytes)) != -1){
                outputStream.write(bytes, 0,len);
                outputStream.flush();
            }

            outputStream.close();
            fileInputStream.close();
        } catch (Exception e) {
            log.error("系统未找到指定文件");
        }
    }

    @GetMapping("/image/views")
    public ResponseEntity<Resource> getImage(@RequestParam String id, @RequestParam String name) {
        Resource img = new FileSystemResource(gameBasePath + id + "/views/" + name);
        return ResponseEntity.ok()
                .contentType(MediaType.IMAGE_JPEG)
                .body(img);
    }

    @GetMapping("/video")
    public ResponseEntity<Resource> streamVideo(@RequestParam String id, @RequestParam String name, @RequestHeader HttpHeaders headers) {
        try {
            String videoPath = gameBasePath + id + "/views/" + name;
            Resource video = new FileSystemResource(videoPath);

            if (!video.exists() || !video.isReadable()) {
                return ResponseEntity.notFound().build();
            }

            long fileSize = video.contentLength();
            List<HttpRange> ranges = headers.getRange();
            if (ranges.isEmpty()) {
                // 如果没有 Range 请求头，返回整个文件
                return ResponseEntity.ok()
                        .contentType(MediaTypeFactory.getMediaType(video).orElse(MediaType.APPLICATION_OCTET_STREAM))
                        .contentLength(fileSize)
                        .body(video);
            }

            // 处理 Range 请求头
            HttpRange range = ranges.get(0);
            long start = range.getRangeStart(fileSize);
            long end = range.getRangeEnd(fileSize);
            long rangeLength = end - start + 1;

            String contentRange = "bytes " + start + "-" + end + "/" + fileSize;

            RandomAccessFile videoFile = new RandomAccessFile(video.getFile(), "r");
            videoFile.seek(start);

            byte[] data = new byte[(int) rangeLength];
            videoFile.read(data, 0, (int) rangeLength);

            return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT)
                    .header(HttpHeaders.CONTENT_TYPE, MediaTypeFactory.getMediaType(video).orElse(MediaType.APPLICATION_OCTET_STREAM).toString())
                    .header(HttpHeaders.CONTENT_RANGE, contentRange)
                    .header(HttpHeaders.CONTENT_LENGTH, String.valueOf(rangeLength))
                    .body(new ByteArrayResource(data));
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

}
